package com.calculator.demo;

import java.util.ArrayList;

/**
 * @description: 调用者，负责封装命令，调用命令执行
 * @author: YanXun
 * @date: 2023/3/6
 **/
public class Invoker {

    //计算器工具类
    private Calculator calculator = new Calculator();
    //记录历史命令，用来进行redo/undo操作
    private ArrayList<Command> commands = new ArrayList<Command>();
    //当前命令的索引
    private int current = 0;

    /**
     * 重做步骤
     *
     * @param levels 要重做的步骤数
     */
    public void redo(int levels) {

        System.out.println("重做" + levels + "步");
        while (levels > 0 && current < commands.size()) {
            commands.get(current).execute();
            current++;
            levels--;
        }
    }

    /**
     * 撤销步骤
     *
     * @param levels 要撤销最近的几个步骤
     */
    public void undo(int levels) {
        System.out.println("撤销" + levels + "步");
        for (int i = levels; i > 0; i--) {
            if (current > 0) {
                --current;
                commands.get(current).unexecute();
            } else {
                System.out.println("已回到初始状态");
                break;
            }
        }
    }

    /**
     * 计算
     *
     * @param operator 操作符
     * @param operand  操作数
     */
    public void compute(char operator, int operand) {
        Command command = new CalculatorCommand(calculator, operator, operand);
        command.execute();
        //处于undo和redo中间的计算步骤。将undo/redo命令索引之后的命令全部删除
        if (current < this.commands.size()) {
            int gap = this.commands.size() - current;
            while (gap > 0) {
                this.commands.remove(this.commands.size() - 1);
                gap--;
            }
        }
        commands.add(command);
        current++;
    }
}

